package shared.file

import java.io._

trait FileReference {
  
  val md5: String
  
  def size: Long
  
  def name: String
  
  def path: String
  
  def description: String
  
  def keywords: String
  
  override def hashCode = md5.hashCode + (size.asInstanceOf[Int])
  
  override def equals(a: Any) = {
    a match {
      case x: FileReference => x.getClass == this.getClass && x.size == this.size && x.md5 == this.md5
      case _ => false
    }
  }
  
  override def toString = {
    path + " " + { if(description.size > 0) "desc: "+ description else "" } + " " + {if(keywords.size > 0) "keys: " + keywords else ""} 
  }
  
}

class RemoteFile(val md5: String, val size: Long, val name: String, val path: String, var description: String, var keywords: String) extends Serializable with FileReference {
  def this(f: FileReference) = this(f.md5, f.size, f.name, f.path, f.description, f.keywords)
}

class LocalFileReference(val file: File, val root: File) extends FileReference with IOAware {
  val path = {
    var p = file.getName
    var parent = file.getParentFile
    while(parent != root) {
      p = parent.getName + "/" + p
      parent = parent.getParentFile
    }
    parent.getName + "/" + p
  }
  
  def size = file.length
  def name = file.getName
  var keywords = ""
  var description = ""
  
  lazy val md5 = {
    import java.security._
    val md = MessageDigest.getInstance("MD5")
    eachChunk(open, new Array[Byte](10240)) { (buf, ind) =>
      md.update(buf, 0, ind)
    }
    md.digest.map(Integer.toHexString(_)).mkString("", "", "")
  }
  
  def toRemote = new RemoteFile(this)
  
  def open:InputStream = new FileInputStream(file)
  
  def toXML = {
    <localFile>
      <path>{file.getAbsolutePath}</path>
      <parent>{root.getAbsolutePath}</parent>
      <description>{description}</description>
      <kw>{keywords}</kw>
    </localFile>
  }
  

  
  override def hashCode = this.file.hashCode
  
  override def equals(o: Any) = {
    o match {
      case f: LocalFileReference => this.file.getAbsoluteFile == f.file.getAbsoluteFile
      case _ => false
    }
  }
 
}